home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------------
- # MPing 1.1 - MacTCP Ping Tool
- #
- # Copyright © Apple Computer, Inc. 1990-1991
- # All rights reserved.
- #
- # Versions:
- # 1.1 September 25, 1991.
- #
- # File:
- # MPing.c
- #
- # Components:
- # AddressXlation.h
- # MacTCPCommonTypes.h
- # Makefile
- # MiscIPPB.h
- # MPing.c
- # MPing.h
- # MPing.r
- # MPingDlg.c
- # MPingExtern.h
- # MPingGlobals.h
- # MPingIcmp.c
- # MPingWindow.c
- # resolver.c
- ------------------------------------------------------------------------------*/
-
- #include <values.h>
- #include <types.h>
- #include <quickdraw.h>
- #include <fonts.h>
- #include <events.h>
- #include <controls.h>
- #include <windows.h>
- #include <menus.h>
- #include <textedit.h>
- #include <dialogs.h>
- #include <desk.h>
- #include <scrap.h>
- #include <toolutils.h>
- #include <memory.h>
- #include <segload.h>
- #include <files.h>
- #include <osutils.h>
- #include <osevents.h>
- #include <diskinit.h>
- #include <packages.h>
- #include <traps.h>
- #include <strings.h>
- #include <Errors.h>
- #include <Devices.h>
- #include <String.h>
- #include <StdLib.h>
- #include <StdIO.h>
- #include <AppleTalk.h>
-
- #include "MacTCPCommonTypes.h"
- #include "MiscIPPB.h"
- #include "AddressXlation.h"
- #include "MPing.h"
- #include "MPingGlobals.h"
-
- #ifndef DEBUG
- #define DEBUG 1
- #endif
-
- Boolean waiting = true;
- char gHostAddress[255]; /* Host address */
- char gData[MAX_ICMP_SIZE]; /* ICMP data to be transmitted */
- char gPattern[MAX_ICMP_SIZE]; /* ICMP data pattern to be transmitted */
- char gPatData[MAX_ICMP_SIZE]; /* ICMP data created from the pattern */
- char *gDataPtr; /* pointer to the data actually being transmitted */
- long gSize; /* size of the ICMP packet */
- long gTempCount=1; /* used for sending fixed no. of packets */
- long gCount; /* no. of ICMP data packets to be transmitted */
- long gWait; /* wait no. of ticks before sending each packet */
- Boolean gTextPattern; /* true to send text, false to send pattern */
- Boolean gQuietVerbose; /* true to quiet, false to verbose */
- Boolean gFixedNoOfPkts; /* true to send fixed no. of packets, false to continue */
- struct IPParamBlock gIopbBlk[MAX_IOPB_QUEUE]; /* allocate iopb blocks from this */
- struct EchoResponseStatus gResponseStatus; /* status of echo response */
- char gIPOptionsBlk[MAX_IOPB_QUEUE][MAX_OPT_SIZE]; /* IP options block */
- char gIPOptionResponse[MAX_OPT_SIZE]; /* response from destination host */
- short gIopbIndex; /* circular queue, with this index */
-
- struct Record_Route_Info gRecord_route;
- struct Record_Route_Info gLooseSourceRR;
- struct Record_Route_Info gStrictSourceRR;
- struct Security_Info gSecurity_Opt;
- struct Stream_Indentifier_Info gStream_ID;
- struct Internet_Timestamp_Info gInternetTimeStamp;
-
- Boolean gRR=false; /* flag for Record Route option */
- Boolean gLSRR=false; /* flag for Loose Source Record Route option */
- Boolean gSSRR=false; /* flag for Strict Source Record Route option */
- Boolean gSecurity=false; /* flag for Security option */
- Boolean gSID=false; /* flag for Stream ID option */
- Boolean gTimestamp=false; /* flag for Internet Timestamp option */
-
- Boolean gSessionComplete=false; /* if false don't send packet, else do */
-
- Boolean gResponsePrinted=true; /* used in verbose option */
-
- short gDrvrRefNum; /* reference number of .ipp driver */
- unsigned long gSourceHostAddress; /* ip address of the source host */
- char gSourceAddress[16]; /* in character format */
- unsigned long gDestHostAddress=0; /* ping to this host address */
- char gDestAddress[16]; /* in character format */
-
- struct PingStatistics gIcmpStat; /* used to print icmp ping statistics */
-
- void DoIcmpPing(void);
- OSErr OpenDriverA(short *refnum);
- pascal void appResultProc(struct hostInfo *hostInfoPtr, unsigned longuserDataPtr);
- OSErr IcmpPingSetup(void);
- void FillOurPattern(void);
- void SendIcmpEcho(void);
- void TestCompletion(struct ICMPParamBlock *iopb);
- short FillInIPOptionBlk(char * IPOptionsBlk);
- extern void bzero(char *ptr, int cnt);
- void mycopy(char *dest, char *src, short noOfBytes);
- extern void WarnUser(short error);
- void IsHostAlive(void);
- void TestCompletion1(struct ICMPParamBlock *iopb);
-
-
- void SendIcmpEcho(void)
- {
- OSErr err;
- short qStart, qEnd; /* indices for circular queue */
- short optionLength;
-
- if ((gFixedNoOfPkts == false) || (gTempCount)) { /* send fixed no. of packets, check the count */
- qStart = gIopbIndex; /* find the first free block */
- qEnd = (gIopbIndex ? gIopbIndex-1 : MAX_IOPB_QUEUE-1);
-
- while ( (gIopbBlk[qStart].ioResult == 1) && (qStart != qEnd) ) {
- qStart++;
- if (qStart == MAX_IOPB_QUEUE)
- qStart = 0;
- }
- gIopbIndex = qStart;
- if (gIopbBlk[gIopbIndex].ioResult < 1) {
- gIcmpStat.totPktOut++;
- gIopbIndex = qStart;
- bzero((char *)&(gIopbBlk[gIopbIndex]), sizeof(struct IPParamBlock));
- gIopbBlk[gIopbIndex].ioCRefNum = gDrvrRefNum;
- gIopbBlk[gIopbIndex].csCode = ipctlEchoICMP;
- gIopbBlk[gIopbIndex].csParam.IPEchoPB.dest = gDestHostAddress;
- gIopbBlk[gIopbIndex].csParam.IPEchoPB.data.ptr = gDataPtr;
- gIopbBlk[gIopbIndex].csParam.IPEchoPB.data.length = gSize;
- gIopbBlk[gIopbIndex].csParam.IPEchoPB.timeout = 1;
- optionLength = FillInIPOptionBlk(gIPOptionsBlk[gIopbIndex]);
- if (optionLength > MAX_OPT_SIZE) {
- gIopbBlk[gIopbIndex].csParam.IPEchoPB.options = (Ptr) nil;
- gIopbBlk[gIopbIndex].csParam.IPEchoPB.optLength = 0;
- }
- else {
- gIopbBlk[gIopbIndex].csParam.IPEchoPB.options = (Ptr) gIPOptionsBlk[gIopbIndex];
- gIopbBlk[gIopbIndex].csParam.IPEchoPB.optLength = optionLength;
- }
- gIopbBlk[gIopbIndex].csParam.IPEchoPB.icmpCompletion = (ICMPEchoNotifyProc) TestCompletion;
- gIopbBlk[gIopbIndex].csParam.IPEchoPB.userDataPtr = gIcmpStat.totPktOut;
- err = PBControl((ParamBlockRec *)&(gIopbBlk[gIopbIndex]), true);
- }
- gIopbIndex++; /* mark next queue element as current */
- if (gIopbIndex == MAX_IOPB_QUEUE) gIopbIndex = 0;
- }
- if ((gFixedNoOfPkts == true) && (gTempCount <= 0)) /* we are done */
- gSessionComplete = true;
- /* see if we are not getting any responses after sending many echoes */
- if ((gIcmpStat.totPktOut >= MAX_PKT_NO_RESP) && (gIcmpStat.totPktIn == 0))
- gSessionComplete = true;
- }
-
- void TestCompletion(iopb)
- struct ICMPParamBlock *iopb;
- {
- unsigned long thisTime;
-
- if (gQuietVerbose == true)
- gResponsePrinted = true;
- else gResponsePrinted = false;
- thisTime = iopb->icmpEchoInfo.echoReplyIn - iopb->icmpEchoInfo.echoRequestOut;
- gResponseStatus.rt_time = thisTime;
- gResponseStatus.pkt_len = iopb->icmpEchoInfo.echoedData.length - 8;
- gResponseStatus.pkt_no = iopb->icmpEchoInfo.userDataPtr;
-
- if (iopb->ioResult == noErr) {
- gResponseStatus.response_ok = true;
- if (iopb->icmpEchoInfo.options != nil)
- mycopy(gIPOptionResponse, iopb->icmpEchoInfo.options, sizeof(struct Record_Route_Info));
-
- gIcmpStat.totPktIn++; /* update ICMP ping statistics */
- gIcmpStat.totTime += thisTime;
- if (iopb->icmpEchoInfo.userDataPtr == 1) { /* first packet */
- gIcmpStat.minTime = thisTime;
- gIcmpStat.maxTime = thisTime;
- }
- else {
- if (thisTime < gIcmpStat.minTime)
- gIcmpStat.minTime = thisTime; /* update min round-trip time */
- else
- if (thisTime > gIcmpStat.maxTime)
- gIcmpStat.maxTime = thisTime; /* update max round-trip time */
- }
- if ((gFixedNoOfPkts == true) && (gTempCount > 0))
- gTempCount--; /* we are not considering duplicate replies */
- }
- else {
- gIcmpStat.totPktBad++;
- gResponseStatus.response_ok = false;
- }
- }
-
- OSErr IcmpPingSetup(void)
- {
- OSErr err;
- struct hostInfo hostInfo;
- unsigned long userDataPtr = 0X123456789;
- short refNum;
- char driverName[] = {'\4', '.', 'i', 'p', 'p'};
-
- gIcmpStat.minTime = 0;
- gIcmpStat.avgTime = 0;
- gIcmpStat.maxTime = 0;
- gIcmpStat.totTime = 0;
- gIcmpStat.totPktOut = 0;
- gIcmpStat.totPktIn = 0;
- gIcmpStat.totPktBad = 0;
-
- gResponseStatus.pkt_no = 0;
- gResponseStatus.rt_time = 0;
- gResponseStatus.pkt_len = 0;
- gResponseStatus.response_ok = true;
-
- err = OpenDriverA(&refNum);
- if (err == noErr) {
- gDrvrRefNum = refNum;
- err = StrToAddr(gHostAddress, &hostInfo, (ResultProcPtr) appResultProc, (char *)userDataPtr);
- if (hostInfo.rtnCode == cacheFault) {
- while (waiting == true) {};
- waiting = true;
- }
- gDestHostAddress = hostInfo.addr[0];
- (void) AddrToStr(gDestHostAddress, gDestAddress);
- err = hostInfo.rtnCode;
- }
-
- bzero((char *) &(gIopbBlk[0]), sizeof(struct IPParamBlock) * MAX_IOPB_QUEUE);
- bzero(gIPOptionResponse, MAX_OPT_SIZE);
- if (err == noErr) { /* set up the global environment */
- if (gCount < 0) gCount = DEFAULT_PKT_COUNT;
- if (gSize <= 0) gSize = DEFAULT_ICMP_SIZE;
- else
- if (gSize > MAX_ICMP_SIZE) gSize = MAX_ICMP_SIZE;
- if (gWait < MIN_TIME_DELAY) gWait = MIN_TIME_DELAY;
- if (gFixedNoOfPkts == true) gTempCount = gCount;
- if (gTextPattern == true) { /* fill the packet with the data */
- gDataPtr = &gData;
- }
- else { /* fill the packet with the pattern */
- FillOurPattern();
- gDataPtr = &gPatData;
- }
- gIopbIndex = 0;
- }
- return(err);
- }
-
- OSErr OpenDriverA(refnum)
- short *refnum;
- {
- IOParam iopb;
- struct IPParamBlock1 tiopb;
- OSErr err;
- static char driverName[] = {'\4', '.', 'i', 'p', 'p'};
-
- bzero((char *)&iopb, sizeof(iopb));
- iopb.ioNamePtr = &driverName;
- iopb.ioPermssn = fsCurPerm;
-
- err = PBOpen((ParamBlockRec *)&iopb, false);
- if (err != noErr) {
- return(err);
- }
- else {
- *refnum = iopb.ioRefNum;
- bzero((char *)&tiopb, sizeof(tiopb));
- tiopb.ioCRefNum = *refnum;
- tiopb.csCode = ipctlGetAddr;
- err = PBControl((ParamBlockRec *) &tiopb, false);
- if (err == noErr) {
- gSourceHostAddress = tiopb.ourAddress;
- (void) AddrToStr(gSourceHostAddress, gSourceAddress);
- }
- else gSourceHostAddress = 0;
- }
- return(err);
- }
-
- pascal void appResultProc(hostInfoPtr, userDataPtr)
- struct hostInfo *hostInfoPtr;
- #pragma unsigned long userDataPtr;
- {
- waiting = false;
- }
-
- void FillOurPattern(void)
- {
- short i, j, k, index=0, len;
- char tHighByte[] = {0x0F,0x1F,0x2F,0x3F,0x4F,0x5F,0x6F,0x7F,0x8F,0x9F,
- 0xAF,0xBF,0xCF,0xDF,0xEF,0xFF};
- char tLowByte[] = {0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
- 0xFA,0xFB,0xFC,0xFD,0xFE,0xFF};
-
- len = strlen(gPattern);
- for (i=0; (i<len) && (index!=-1); i++) {
- if ((gPattern[i] >= '0') && (gPattern[i] <= '9'))
- index = gPattern[i] - '0';
- else
- if ((gPattern[i] >= 'A') && (gPattern[i] <= 'F'))
- index = gPattern[i] - 'A' + 10;
- else
- if ((gPattern[i] >= 'a') && (gPattern[i] <= 'f'))
- index = gPattern[i] - 'a' + 10;
- else index = -1;
- if (index != -1) {
- for (j=i; j<2*gSize; j+=len) {
- k = j / 2;
- if (!(j % 2)) {
- gPatData[k] |= MASK_HIGH;
- gPatData[k] &= tHighByte[index];
- }
- else {
- gPatData[k] |= MASK_LOW;
- gPatData[k] &= tLowByte[index];
- }
- }
- }
- }
- }
-
- short FillInIPOptionBlk(IPOptionsBlk)
- char *IPOptionsBlk;
- {
- Boolean optionsPresent=false;
- short index1=0;
-
- bzero(IPOptionsBlk, MAX_OPT_SIZE);
-
- if (gRR) {
- bzero((char *)&gRecord_route, 23);
- gRecord_route.opt_type = IPO_RR;
- gRecord_route.opt_len = 23;
- gRecord_route.opt_ptr = 4;
-
- mycopy(IPOptionsBlk, (char *) &gRecord_route, 23);
- index1 += 23;
- optionsPresent = true;
- }
- if (gLSRR) {
- bzero((char *)&gLooseSourceRR, 23);
- gLooseSourceRR.opt_type = IPO_LSRR;
- gLooseSourceRR.opt_len = 23;
- gLooseSourceRR.opt_ptr = 4;
-
- mycopy((char *) &IPOptionsBlk[index1], (char *) &gLooseSourceRR, 23);
- index1 += 23;
- optionsPresent = true;
- }
- if (gSSRR) {
- bzero((char *)&gStrictSourceRR, 23);
- gStrictSourceRR.opt_type = IPO_SSRR;
- gStrictSourceRR.opt_len = 23;
- gStrictSourceRR.opt_ptr = 4;
-
- mycopy((char *) &IPOptionsBlk[index1], (char *) &gStrictSourceRR, 23);
- index1 += 23;
- optionsPresent = true;
- }
- if (gSecurity) {
- bzero((char *)&gSecurity_Opt, 11);
- gSecurity_Opt.opt_type = IPO_SEC;
- gSecurity_Opt.opt_len = 11;
-
- mycopy((char *) &IPOptionsBlk[index1], (char *) &gSecurity_Opt, 11);
- index1 += 11;
- optionsPresent = true;
- }
- if (gSID) {
- bzero((char *)&gStream_ID, 4);
- gStream_ID.opt_type = IPO_SID;
- gStream_ID.opt_len = 4;
-
- mycopy((char *) &IPOptionsBlk[index1], (char *) &gStream_ID, 4);
- index1 += 4;
- optionsPresent = true;
- }
- if (gTimestamp) {
- bzero((char *)&gInternetTimeStamp, 36);
- gInternetTimeStamp.opt_type = IPO_TIME;
- gInternetTimeStamp.opt_len = 36;
- gInternetTimeStamp.opt_ptr = 5;
-
- mycopy((char *) &IPOptionsBlk[index1], (char *) &gInternetTimeStamp, 36);
- index1 += 36;
- optionsPresent = true;
- }
- if (optionsPresent) {
- /* The size of the option block should be of multiple of 4 */
- /* 4 bytes = 32 bits => (bingo !) offset boundary */
- while ((index1 + 1) % 4) /* stuff the required space by */
- IPOptionsBlk[index1++] = IPO_NOP; /* no operation (noop) option code */
- IPOptionsBlk[index1] = IPO_EOL;
- index1++;
- }
- return(index1);
- }
-
- void bzero(ptr, cnt)
- char *ptr;
- int cnt;
- {
- while (cnt--) *ptr++ = 0;
- }
-
- void mycopy(dest, src, noOfBytes)
- char *dest;
- char *src;
- short noOfBytes;
- {
- while (noOfBytes--)
- *dest++ = *src++;
- }
-